#ifdef RFM_LOCAL_C_HASH
// 使用编译时定义的宏 RFM_LOCAL_C_HASH 来初始化这个常量指针
// 这个变量会成为 .so 文件中的一个符号，可以被 dlsym 找到
const char * const rfm_local_c_file_hash = RFM_LOCAL_C_HASH;
#else
// 如果编译时没有定义 RFM_LOCAL_C_HASH 宏 (例如手动编译时忘了加 -D 参数)
// 就发出警告，并将符号定义为 NULL，这样 rfm.c 加载时能发现哈希缺失
#warning "RFM_LOCAL_C_HASH is not defined during compilation. Hash checking willlikely fail."
const char * const rfm_local_c_file_hash = NULL;
#endif

#include <gtk/gtk.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <rfm_addon.h>

extern char rfm_historyFile_ParentDirectory[PATH_MAX];
extern void load_history_for_prompt();
extern void save_current_history();
extern const stdin_cmd_interpretor stdin_cmd_interpretors[];
extern void add_toolbar_buttons(GtkWidget ***buttons, const RFM_ToolButton button_definitions[], const size_t size);
extern void add_file_menuitems(GtkWidget ***menuitems, const RFM_MenuItem menuitem_definitions[], const size_t size);
extern void remove_toolbar_buttons(GtkWidget ***buttons, const size_t size);
extern void remove_file_menuitems(GtkWidget ***menuitems, const size_t size);
extern int ProcessKeyValuePairInCmdOutputFromSearchResult(CALLER_OWN char *oneline, gboolean new_search, char **cmdtemplate, RFM_FileAttributes* fileAttributes,RFM_ChildAttribs *childAttribs);

RFM_ADDON_RESOURCE_TYPE addon_resource = {0};
const enum RFM_ADDON_TYPE addon_type = DirectoryTree;

static char *saved_history_dir = NULL;

#ifdef rfmChinese
#define LISTMAIL "邮件"
#define SYNCMAIL "同步邮件"
#define SearchResultType_muview "首先调用default查询结果类型获取命令输出行列,再使用 mu view 命令读取首列邮件文件内容,把邮件头,转换成前面keyfile要求的键值对格式,最后如同gkeyfile结果类型一样显示.命令举例(注意:Maidir中的文件名会包含冒号,同默认的SearchResultColumnSeperator冲突,要给文件名加引号解决.另外,下面我用cd 加ls而不是locate主要是考虑输出顺序, 而下面{}里的cd是运行于rfm创建的shell子进程,并不是前述rfm内置cd命令):\n" \
"      { cd /home/guyuming/Mail/139INBOX/cur; ls -1td \"$PWD\"/*; }>muview\n" \
"      上面命令也可以简化成如下形式,我这里保留上面作为一个使用bash {} 语法执行命令序列的备忘\n" \
"      ls -1td \"/home/guyuming/Mail/139INBOX/cur\"/*>muview"
#else
#define LISTMAIL "Email"
#define SYNCMAIL "Sync Email"
#define SearchResultType_muview "default search result type will be called first to get command output, then mu view command is used to read mail header and output key value pairs in gkeyfile format, and displayed in the same way as gkeyfile search result type. For example(Note: there will be ':' in file name in Maidir, conflicting with the default SearchResultColumnSeperator, quotation mark should be added around file name to solve this. cd and ls command are used below instead of locate command, because we need the default displaying order of ls command,  and the cd command inside {} is that defined in the shell, not that defined in rfm):\n" \
"      { cd /home/guyuming/Mail/139INBOX/cur; ls -1td \"$PWD\"/*; }>muview\n" \
"      command above can be simplified as what follows. I keep the one above as a sample for bash {} syntax\n" \
"      ls -1td \"/home/guyuming/Mail/139INBOX/cur\"/*>muview"
#endif

static const char *muview[] = { "mu", "view", NULL };
static gchar* MU_VIEW_cmdTemplate[] = { NULL, "mu view %s | rfmGetMailHeaderWithMuView.sh", NULL };
static gchar* MailColumns[] = { "-FileName",",From,Subject,Date,Attachments",NULL };
static const char *listmail[] = { NULL, "ls -1t \"$rfm_curPath\">muview", NULL };
static const char *syncmail[] = { NULL, "mbsync -a --config .mbsyncrc", NULL };//mbsync 名字在gentoo上属于 net-mail/isync 包

RFM_ToolButton tool_buttons_local[] = {
   /* name           icon                       function    		RunCmd      SearchResultView   DirectoryView   Accel                 tooltip                showCondition*/
   { LISTMAIL,       NULL,                      NULL,                   listmail,             FALSE,        TRUE,      0,                     NULL,                    NULL},
   { SYNCMAIL,       NULL,                      NULL,                   syncmail,             FALSE,        TRUE,      0,                     NULL,                    NULL},
};

RFM_MenuItem file_menus_local[] = {
   /* name           mime root        mime sub type            filenameSuffix           OrSearchResultType	func		runCmd            		showCondition	*/
   //{ "test cmd",     "*",              "*",                    NULL,			NULL,			NULL,		testcmd,             		NULL },
   { "Open",         "message",        "rfc822",               NULL,			"muview",               NULL,		muview,                         NULL },
};


RFM_SearchResultType searchresultTypes[] = {
//name	       SearchResultLineProcessingFunc                  showcolumn     SearchResultColumnSeperator  cmdTemplate Description
  {"muview",   ProcessKeyValuePairInCmdOutputFromSearchResult, MailColumns    , "&" , MU_VIEW_cmdTemplate ,          SearchResultType_muview }, //%s in cmdTemplate will be replaced by filename in searchresult
};

void rfm_local_enter(char * Addon_dir) {
     fprintf(stderr,"rfm_local_enter called for %s\n", Addon_dir);
     saved_history_dir=strdup(rfm_historyFile_ParentDirectory);
     save_current_history();
     snprintf(rfm_historyFile_ParentDirectory,sizeof(rfm_historyFile_ParentDirectory),Addon_dir);
     load_history_for_prompt();
     addon_resource.addon_dir = strdup(Addon_dir);
     addon_resource.toolbar_button_definitions_local = tool_buttons_local;
     addon_resource.toolbar_button_definitions_local_array_size = G_N_ELEMENTS(tool_buttons_local);
     addon_resource.file_menuitem_definitions_local = file_menus_local;
     addon_resource.file_menuitem_definitions_local_array_size = G_N_ELEMENTS(file_menus_local);
     addon_resource.searchresulttypes = searchresultTypes;
     addon_resource.searchresulttypes_array_size = G_N_ELEMENTS(searchresultTypes);
     listmail[0] = stdin_cmd_interpretors[0].name;
     syncmail[0] = stdin_cmd_interpretors[0].name;
     MU_VIEW_cmdTemplate[0] = stdin_cmd_interpretors[0].name;
     add_toolbar_buttons(&(addon_resource.tool_bar_buttons_local),tool_buttons_local, addon_resource.toolbar_button_definitions_local_array_size);
     add_file_menuitems(&(addon_resource.menuItems_local), file_menus_local, addon_resource.file_menuitem_definitions_local_array_size);
}

void rfm_local_leave() {
     fprintf(stderr,"rfm_local_leave called for %s\n", addon_resource.addon_dir);
     if (saved_history_dir) {
         save_current_history();
         sprintf(rfm_historyFile_ParentDirectory,"%s",saved_history_dir);
         free(saved_history_dir);
         load_history_for_prompt();
     }

     remove_toolbar_buttons(&(addon_resource.tool_bar_buttons_local),addon_resource.toolbar_button_definitions_local_array_size);
     remove_file_menuitems(&(addon_resource.menuItems_local), addon_resource.file_menuitem_definitions_local_array_size);
}
